﻿//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Mapping Application Block
//===============================================================================

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;
using Microsoft.Practices.ObjectBuilder2;
using EntLibContrib.Mapping.Instrumentation;

namespace EntLibContrib.Mapping.Configuration
{
	/// <summary>
	/// Helper utility for assembler and policy creators
	/// </summary>
	public static class MappingAssemblerHelper
	{
		#region Fields
		private readonly static ConfigurationReflectionCache localReflectionCache = new ConfigurationReflectionCache();
		#endregion

		#region Public Static Methods
		/// <summary>
		/// Creates a map dictionary.
		/// </summary>
		/// <param name="maps">The maps.</param>
		/// <param name="context">The object builder context.</param>
		/// <param name="configurationSource">The configuration source.</param>
		/// <param name="reflectionCache">The reflection cache.</param>
		/// <returns>a populated <see cref="MapDictionary"/> instance from configuration</returns>
		public static MapDictionary CreateMapDictionary(NamedElementCollection<MapData> maps,
																										IBuilderContext context,
																										IConfigurationSource configurationSource,
																										ConfigurationReflectionCache reflectionCache)
		{
			ConfigurationReflectionCache configurationReflectionCache = reflectionCache;
			if (configurationReflectionCache == null)
				configurationReflectionCache = localReflectionCache;

			MapDictionary mapDictionary = new MapDictionary();

			foreach (MapData mapData in maps)
			{
				IMap map = MapCustomFactory.Instance.Create(context, mapData, configurationSource, configurationReflectionCache);
				mapDictionary.Add(map.Name, map);
			}

			return mapDictionary;
		}

		/// <summary>
		/// Creates an instrumentation provider.
		/// </summary>
		/// <param name="name">The name.</param>
		/// <param name="configurationSource">The configuration source.</param>
		/// <param name="reflectionCache">The reflection cache.</param>
		/// <returns></returns>
		public static MappingInstrumentationProvider CreateInstrumentationProvider(string name,
																																							IConfigurationSource configurationSource,
																																							ConfigurationReflectionCache reflectionCache)
		{
			ConfigurationReflectionCache configurationReflectionCache = reflectionCache;
			if (configurationReflectionCache == null)
				configurationReflectionCache = localReflectionCache;

			MappingInstrumentationProvider instrumentationProvider = new MappingInstrumentationProvider();
			new InstrumentationAttachmentStrategy().AttachInstrumentation(name, instrumentationProvider, configurationSource, configurationReflectionCache);

			return instrumentationProvider;
		}
		#endregion
	}
}
